package com.huatai.bpmn.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.huatai.bpmn.entity.dto.ApiRequestDto;
import com.huatai.bpmn.entity.dto.SqlTypeDto;
import com.huatai.bpmn.utils.SqlUtil;
import com.huatai.common.api.R;
import com.huatai.common.httputil.HttpRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * @author gusiyi
 * @version 1.0
 * @className ApiRequestController
 * @description 描述：
 * @date 2023/7/31 17:17
 */
@RestController
@Api(value = "请求后台controller",tags = "请求后台controller")
@RequestMapping("/request")
@Slf4j
public class ApiRequestController {

	@PostMapping("/getResByUrl")
	@ApiOperation("请求Url获取返回结果")
	@ApiOperationSupport(includeParameters = {
		"apiRequestDto.url",
		"apiRequestDto.requestBody",
		"apiRequestDto.requestMethod",
		"apiRequestDto.defaultValue",
		"apiRequestDto.resultPath"
	})
	public R<JSONObject> getResult(@RequestBody ApiRequestDto apiRequestDto){
		JSONObject resultJson = new JSONObject();
		String url = apiRequestDto.getUrl();
		JSONObject requestBody = apiRequestDto.getRequestBody();
		String defaultValue = apiRequestDto.getDefaultValue();
		String resultPath = apiRequestDto.getResultPath();
		String method = apiRequestDto.getRequestMethod();
		if ("get".equalsIgnoreCase(method)){
			url +="?";
			Set<String> keySet = requestBody.keySet();
			for(String key : keySet){
				String value = requestBody.getString("key");
				url += key+"="+value+"&";
			}
			url = url.substring(0,url.length()-1);
			Optional<JSONObject> resultOpt = HttpRequest
				.get(url)
				.execute()
				.onFailed((request, e) -> log.error("请求失败,原因:{}", e.getMessage()))
				.onSuccessOpt(responseSpec -> responseSpec.asValue(JSONObject.class));
			log.info("resultOpt:{}",resultOpt.toString());
			JSONObject result = resultOpt.orElse(new JSONObject());
			try{
				String[] paths = resultPath.split("\\.");
				String valByPath = getValByPath(0, paths, result);
				resultJson.put("data",valByPath);
			}catch (Exception e){
				log.error(e.getMessage());
				resultJson.put("data",defaultValue);
			}

		}else if ("post".equalsIgnoreCase(method)){
			Optional<JSONObject> resultOpt = HttpRequest
				.post(url)
				.bodyString(requestBody.toJSONString())
				.execute()
				.onFailed((request, e) -> log.error("请求失败,原因:{}", e.getMessage()))
				.onSuccessOpt(responseSpec -> responseSpec.asValue(JSONObject.class));
			log.info("resultOpt:{}",resultOpt.toString());
			JSONObject result = resultOpt.orElse(new JSONObject());
			try{
				String[] paths = resultPath.split("\\.");
				String valByPath = getValByPath(0, paths, result);
				resultJson.put("data",valByPath);
			}catch (Exception e){
				log.error(e.getMessage());
				resultJson.put("data",defaultValue);
			}
		}
		return R.data(resultJson);
	}

	@PostMapping("/getSqlTypeData")
	@ApiOperation("获取sql下拉框类型数据")
	@ApiOperationSupport(includeParameters = {
		"sqlTypeDto.sql"
	})
	public R<List<Map<String, Object>>> getSqlData(@RequestBody SqlTypeDto sqlTypeDto){
		String sql = sqlTypeDto.getSql();
		boolean checkResult = SqlUtil.checkQuerySql(sql);
		if (checkResult){
			return R.fail("Sql语句中包含违规关键字,SQL不合法");
		}else {
			List<Map<String, Object>> resultList = SqlRunner.db().selectList(sql);
			return R.data(resultList);
		}
	}

	private String getValByPath(int index,String[] paths,JSONObject json){
		if (index == paths.length-1){
			String val = json.getString(paths[index]);
			if (val == null){
				throw new RuntimeException("接口未获取到数据，使用默认值");
			}else {
				return val;
			}
		}
		return getValByPath(index+1,paths,json.getJSONObject(paths[index]));
	}
}
